home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / editors / mjovesrc.zoo / io.c < prev    next >
C/C++ Source or Header  |  1992-04-04  |  31KB  |  1,550 lines

  1. /***************************************************************************
  2.  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  3.  * is provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is    *
  5.  * included in all the files.                                              *
  6.  ***************************************************************************/
  7.  
  8. #include "jove.h"
  9. #include "list.h"
  10. #include "fp.h"
  11. #include "termcap.h"
  12. #include "ctype.h"
  13. #include "disp.h"
  14. #include "scandir.h"
  15.  
  16.  
  17. #ifdef    IPROCS
  18. # include <signal.h>
  19. #endif
  20.  
  21. #ifdef    MAC
  22. # include "mac.h"
  23. #else
  24. # include <sys/stat.h>
  25. #endif
  26.  
  27. #ifdef    UNIX
  28. # include <sys/file.h>
  29. #endif
  30.  
  31. #ifdef    MSDOS
  32. # include <fcntl.h>
  33. # include <io.h>
  34. # include <direct.h>
  35. # include <dos.h>
  36. #endif    /* MSDOS */
  37.  
  38. #ifdef MiNT
  39. #include <mintbind.h>
  40. #endif
  41.  
  42. #include <errno.h>
  43.  
  44. private struct block
  45.     *lookup proto((int /* promoted short */));
  46.  
  47. private char
  48. #if    defined(MSDOS) || defined(MiNT)
  49.     *fixpath proto((char *)),
  50. #endif
  51.     *getblock proto((daddr, bool));
  52.  
  53. private bool
  54.     f_getputl proto((struct line *line,struct FileStruct *fp));
  55.  
  56. private void
  57. #if    defined(MSDOS) || defined(MiNT)
  58.     abspath proto((char *, char *)),
  59. #endif  /* MSDOS || MiNT */
  60.     file_backup proto((char *fname));
  61.  
  62. #if    defined(MSDOS) || defined(MiNT)
  63. private int
  64.     Dchdir proto((char *));
  65. #endif
  66.  
  67. long    io_chars;        /* number of chars in this open_file */
  68. int    io_lines;        /* number of lines in this open_file */
  69.  
  70. #ifdef    pdp11
  71. char    *iobuff,
  72.     *genbuf,
  73.     *linebuf;
  74. #else
  75. char    iobuff[LBSIZE],
  76.     genbuf[LBSIZE],
  77.     linebuf[LBSIZE];
  78. #endif
  79.  
  80. #ifdef    BACKUPFILES
  81. bool    BkupOnWrite = OFF;
  82. #endif
  83.  
  84. #if    !defined(MSDOS) && !defined(MiNT)
  85. #define    Dchdir(to)  chdir(to)
  86. #endif
  87.  
  88. #ifdef MSDOS
  89.  
  90. private int            /* chdir + drive */
  91. Dchdir(to)
  92. char *to;
  93. {
  94.     unsigned d, dd, n;
  95.  
  96.     if (to[1] == ':') {
  97.         d = CharUpcase(to[0]) - 'A';
  98.         /* ??? only 16 drives? */
  99.         if (d >= 16)
  100.             complain("invalid drive");
  101.         _dos_getdrive(&dd);
  102.         if (dd != d)
  103.             _dos_setdrive(d, &n);
  104.         if (to[2] == '\0') {
  105.             /* ??? Is this correct? DHR
  106.              * Current path on this drive might not be the root.
  107.              */
  108.             return 0;
  109.         }
  110.     }
  111.     return chdir(to);
  112. }
  113. #endif /* MSDOS */
  114.  
  115. #ifdef MiNT
  116.  
  117. private int            /* chdir + drive */
  118. Dchdir(to)
  119. char *to;
  120. {
  121.     int d, dd;
  122.  
  123.     if (to[1] == ':') {
  124.         d = CharUpcase(to[0]) - 'A';
  125.         dd = Dgetdrv();
  126.         if (dd != d)
  127.             Dsetdrv(d);
  128.     }
  129.     if ((to[2] == '\0') || ((to[2] == '/') && (to[3] == '\0')))
  130.         return chdir("\\");
  131.     return chdir(to);
  132. }
  133. #endif /* MiNT */
  134.  
  135. #if defined(MSDOS) || defined(MiNT)
  136. private char *
  137. fixpath(p)
  138. char *p;
  139. {
  140.     char *pp = p;
  141.  
  142.     while (*p) {
  143.         if (*p == '\\')
  144.             *p = '/';
  145.         p++;
  146.     }
  147.     return strlwr(pp);
  148. }
  149. #endif /* MiNT || MSDOS */
  150.  
  151. #ifdef MSDOS
  152. private void
  153. abspath(so, dest)
  154. char *so, *dest;
  155. {
  156.     char cwd[FILESIZE], cwdD[3], cwdDIR[FILESIZE], cwdF[9], cwdEXT[5],
  157.          soD[3], soDIR[FILESIZE], soF[9], soEXT[5];
  158.     char *drive, *path;
  159.  
  160.     _splitpath(fixpath(so), soD, soDIR, soF, soEXT);
  161.     getcwd(cwd, FILESIZE);
  162.     if (*soD != '\0') {
  163.         Dchdir(soD);                /* this is kinda messy    */
  164.         getcwd(cwdDIR, FILESIZE);    /* should probably just    */
  165.         Dchdir(cwd);                /* call DOS to do it    */
  166.         strcpy(cwd, cwdDIR);
  167.     }
  168.     (void) fixpath(cwd);
  169.     if (cwd[strlen(cwd)-1] != '/')
  170.         strcat(cwd, "/x.x");    /* need dummy filename */
  171.  
  172.     _splitpath(fixpath(cwd), cwdD, cwdDIR, cwdF, cwdEXT);
  173.  
  174.     drive = (*soD == '\0') ? cwdD : soD;
  175.  
  176.     if (*soDIR != '/')
  177.         path = strcat(cwdDIR, soDIR);
  178.     else
  179.         path = soDIR;
  180.     _makepath(dest, drive, path, soF, soEXT);
  181.     fixpath(dest);    /* can't do it often enough */
  182. }
  183. #endif /* MSDOS */
  184.  
  185. #ifdef MiNT
  186.  
  187. #define MAXPATHLEN 128
  188. #define FILENAMELEN 13
  189. #ifndef NULL
  190. #define NULL (char *)0
  191. #endif
  192. #define lastchar(s) (*(s + strlen(s) - 1))
  193. #define isslash(c) ((c) == '/')
  194. #define isdrive(D) ((strlen(D) == 2) && (lastchar(D) == ':'))
  195.  
  196. private void
  197. abspath(char *rel_path, char *abs_path)
  198. {
  199.     char save_dir[MAXPATHLEN];
  200.     char f_name[FILENAMELEN];
  201.     char *c_ptr;
  202.  
  203.     getcwd(save_dir, MAXPATHLEN);
  204.     if (chdir(rel_path) != -1) {
  205.         getcwd(abs_path, MAXPATHLEN);
  206.         chdir(save_dir);
  207.         return;
  208.     }
  209.     c_ptr = strrchr(rel_path, '/');
  210.     if (!c_ptr) {
  211.         if (isdrive(rel_path)) {
  212.             strcpy(abs_path, rel_path);
  213.             strcat(abs_path, "/");
  214.             return;
  215.         }
  216.         strcpy(abs_path, save_dir);    /* a file name, with no */
  217.         if (!isslash(lastchar(abs_path)))    /* path spec */
  218.             strcat(abs_path, "/");
  219.         strcat(abs_path, rel_path);
  220.         return;                
  221.     }
  222.     strncpy(f_name, c_ptr + 1, FILENAMELEN);
  223.     *c_ptr = '\0';
  224.     if (chdir(rel_path) != -1) {
  225.         getcwd(abs_path, MAXPATHLEN);
  226.         if (!isslash(lastchar(abs_path)))
  227.             strcat(abs_path, "/");
  228.         strcat(abs_path, f_name);
  229.         strcat(rel_path, "/");
  230.         strcat(rel_path, f_name);
  231.         chdir(save_dir);
  232.         return;
  233.     }
  234.     abs_path[0] = (char)NULL;
  235.     return;
  236. }
  237. #endif  /* MiNT */
  238.  
  239. void
  240. close_file(fp)
  241. File    *fp;
  242. {
  243.     if (fp) {
  244.         if (fp->f_flags & F_TELLALL)
  245.             add_mess(" %d lines, %D characters.",
  246.                  io_lines,
  247.                  io_chars);
  248.         f_close(fp);
  249.     }
  250. }
  251.  
  252. /* Write the region from line1/char1 to line2/char2 to FP.  This
  253.    never CLOSES the file since we don't know if we want to. */
  254.  
  255. bool    EndWNewline = 1;
  256.  
  257. void
  258. putreg(fp, line1, char1, line2, char2, makesure)
  259. register File    *fp;
  260. Line    *line1,
  261.     *line2;
  262. int    char1,
  263.     char2;
  264. bool    makesure;
  265. {
  266.     register int    c;
  267.     register char    *lp;
  268.  
  269.     if (makesure)
  270.         (void) fixorder(&line1, &char1, &line2, &char2);
  271.     while (line1 != line2->l_next) {
  272.         lp = lcontents(line1) + char1;
  273.         if (line1 == line2) {
  274.             fputnchar(lp, (char2 - char1), fp);
  275.             io_chars += (char2 - char1);
  276.         } else {
  277.             while ((c = *lp++) != '\0') {
  278.                 jputc(c, fp);
  279.                 io_chars += 1;
  280.             }
  281.         }
  282.         if (line1 != line2) {
  283.             io_lines += 1;
  284.             io_chars += 1;
  285. #ifdef    MSDOS
  286.             jputc('\r', fp);
  287. #endif    /* MSDOS */
  288.             jputc('\n', fp);
  289.         }
  290.         line1 = line1->l_next;
  291.         char1 = 0;
  292.     }
  293.     flushout(fp);
  294. }
  295.  
  296. private void
  297. dofread(fp)
  298. register File    *fp;
  299. {
  300.     char    end[LBSIZE];
  301.     bool    xeof;
  302.     Line    *savel = curline;
  303.     int    savec = curchar;
  304.  
  305.     strcpy(end, linebuf + curchar);
  306.     xeof = f_gets(fp, linebuf + curchar, (size_t) (LBSIZE - curchar));
  307.     SavLine(curline, linebuf);
  308.     while(!xeof) {
  309.         curline = listput(curbuf, curline);
  310.         xeof = f_getputl(curline, fp);
  311.     }
  312.     getDOT();
  313.     linecopy(linebuf, (curchar = strlen(linebuf)), end);
  314.     SavLine(curline, linebuf);
  315.     IFixMarks(savel, savec, curline, curchar);
  316. }
  317.  
  318. void
  319. read_file(file, is_insert)
  320. char    *file;
  321. bool    is_insert;
  322. {
  323.     Bufpos    save;
  324.     File    *fp;
  325.  
  326.     if (!is_insert)
  327.         curbuf->b_ntbf = NO;
  328.     fp = open_file(file, iobuff, F_READ, NO, NO);
  329.     if (fp == NULL) {
  330.         if (!is_insert && errno == ENOENT)
  331.             s_mess("(new file)");
  332.         else
  333.             s_mess(IOerr("open", file));
  334.         return;
  335.     }
  336.     if (!is_insert) {
  337.         set_ino(curbuf);
  338.         set_arg_value((fp->f_flags & F_READONLY)? 1 : 0);
  339.         TogMinor(ReadOnly);
  340.     }
  341.  
  342.     DOTsave(&save);
  343.     dofread(fp);
  344.     if (is_insert && io_chars > 0) {
  345.         modify();
  346.         set_mark();
  347.     }
  348.     SetDot(&save);
  349.     getDOT();
  350.     close_file(fp);
  351. }
  352.  
  353. void
  354. SaveFile()
  355. {
  356.     if (IsModified(curbuf)) {
  357.         if (curbuf->b_fname == NULL)
  358.             WriteFile();
  359.         else {
  360.             filemunge(curbuf->b_fname);
  361.             chk_mtime(curbuf, curbuf->b_fname, "save");
  362.             file_write(curbuf->b_fname, NO);
  363.         }
  364.     } else
  365.         message("No changes need to be written.");
  366. }
  367.  
  368. char    *HomeDir;    /* home directory */
  369. size_t    HomeLen;    /* length of home directory string */
  370.  
  371. private List        *DirStack = NULL;
  372. #define dir_name(dp)    ((char *) list_data((dp)))
  373. #define PWD_PTR        (list_data(DirStack))
  374. #define PWD        ((char *) PWD_PTR)
  375.  
  376. char *
  377. pwd()
  378. {
  379.     return (char *) PWD_PTR;
  380. }
  381.  
  382. char *
  383. pr_name(fname, okay_home)
  384. char    *fname;
  385. int    okay_home;
  386. {
  387.     int    n;
  388.  
  389.     if (fname != NULL) {
  390.         n = numcomp(fname, PWD);
  391.  
  392.         if ((PWD[n] == '\0') &&    /* Matched to end of PWD */
  393.             (fname[n] == '/'))
  394.             return fname + n + 1;
  395.  
  396.         if (okay_home && strcmp(HomeDir, "/") != 0
  397.         && strncmp(fname, HomeDir, HomeLen) == 0
  398.         && fname[HomeLen] == '/')
  399.         {
  400.             static char    name_buf[100];
  401.  
  402.             swritef(name_buf, sizeof(name_buf),
  403.                 "~%s", fname + HomeLen);
  404.             return name_buf;
  405.         }
  406.     }
  407.     return fname;
  408. }
  409.  
  410. void
  411. Chdir()
  412. {
  413.     char    dirbuf[FILESIZE];
  414.  
  415. #ifdef    MSDOS
  416.     fmask = 0x10;
  417. #endif
  418.     (void) ask_file((char *)NULL, PWD, dirbuf);
  419. #ifdef    MSDOS
  420.     fmask = 0x13;
  421. #endif
  422.     if (Dchdir(dirbuf) == -1)
  423.     {
  424.         s_mess("cd: cannot change into %s.", dirbuf);
  425.         return;
  426.     }
  427.     UpdModLine = YES;
  428.     setCWD(dirbuf);
  429.     prCWD();
  430. #ifdef    MAC
  431.     Bufchange = YES;
  432. #endif
  433. }
  434.  
  435. #ifdef    UNIX
  436.